home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / programming / other / gtdrag / examples / treetest.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  13KB  |  479 lines

  1. ;/* treetest.c - Test for the gtdrag.library, 7.6.1999
  2. ;**
  3. ;** Copyright ©1999 pinc Software.
  4. ;** All rights reserved.
  5. ;**
  6. sc treetest.c link lib=lib:debug.lib ign=73 nodbg data=near parm=b nochkabort nostkchk strmer streq to=ram:treetest
  7. run ram:treetest
  8. quit
  9. */
  10.  
  11.  
  12. /* This example shows how to use the treeview included in the
  13. ** gtdrag-library.
  14. ** This is done via a standard gadtools listview and a special
  15. ** render hook.
  16. ** Furthermore, this example make use of lots of the tree support
  17. ** functions of the library.
  18. **
  19. ** It's a very simple example but you may use this code to produce
  20. ** one at your own.
  21. **
  22. ** Although I tried hardly to not produce any errors, I cannot give
  23. ** any guaranties. Neither I nor pinc Software is liable for any
  24. ** problems you might have with it.
  25. ** The usage of this example is on your own risk.
  26. */
  27.  
  28.  
  29. #define INTUI_V36_NAMES_ONLY
  30. #define __USE_SYSBASE
  31.  
  32. #include <exec/libraries.h>
  33. #include <exec/nodes.h>
  34. #include <exec/lists.h>
  35. #include <exec/ports.h>
  36. #include <exec/memory.h>
  37. #include <intuition/intuition.h>
  38. #include <intuition/gadgetclass.h>
  39. #include <graphics/gfx.h>
  40. #include <graphics/gfxmacros.h>
  41. #include <libraries/gadtools.h>
  42. #include <libraries/gtdrag.h>
  43. #include <libraries/asl.h>
  44. #include <dos/dos.h>
  45. #include <dos/dosextens.h>
  46. #include <dos/exall.h>
  47. #include <dos/dostags.h>
  48.  
  49. #include <clib/alib_protos.h>
  50. #include <clib/alib_stdio_protos.h>
  51. #include <clib/gtdrag_protos.h>
  52. #include <proto/exec.h>
  53. #include <proto/gadtools.h>
  54. #include <proto/intuition.h>
  55. #include <proto/graphics.h>
  56. #include <proto/layers.h>
  57. #include <proto/utility.h>
  58. #include <proto/dos.h>
  59. #include <pragmas/gtdrag_pragmas.h>
  60.  
  61. #include <stdlib.h>
  62. #include <ctype.h>
  63. #include <string.h>
  64.  
  65.  
  66. /**************** some useful definitions ****************/
  67.  
  68. void kprintf(STRPTR,...);
  69. #define bug kprintf
  70.  
  71. #define TLn(t) TextLength(&scr->RastPort,t,strlen(t))
  72. #define foreach(l,v) for(v = (APTR)((struct List *)l)->lh_Head;((struct Node *)v)->ln_Succ;v = (APTR)((struct Node *)v)->ln_Succ)
  73.  
  74.  
  75. #define PUDDLESIZE 8192                                        // for CreatePool()
  76. #define MULTIVIEW "sys:Utilities/Multiview"                    // "show" programme
  77. #define SEARCH_DIRECTORY "ram:"                                // directory displayed
  78. #define SEARCH_DEPTH 4                                         // depth of the tree
  79. #define OUTPUT "CON://400/200/TreeView-Output/AUTO/CLOSE/WAIT"
  80.  
  81.  
  82. /**************** the menu definition ****************/
  83.  
  84. struct NewMenu NMenu[] =
  85. {
  86.   {NM_TITLE,"Control",         0,0,0,0},
  87.   {NM_ITEM, "Open all",      "O",0,0,0},
  88.   {NM_ITEM, "Close all",     "C",0,0,0},
  89.   {NM_ITEM, NM_BARLABEL,       0,0,0,0},
  90.   {NM_ITEM, "About...",      "?",0,0,0},
  91.   {NM_ITEM, "Quit",          "Q",0,0,0},
  92.  
  93.   {NM_END,  NULL,          0,0,0,0}
  94. };
  95.  
  96.  
  97. /**************** global variables ****************/
  98.  
  99. struct Screen *scr;
  100. struct Window *win;
  101. struct IntuiMessage imsg;
  102. struct Menu *menu;
  103. struct Library *GTDragBase;
  104. struct Gadget *glist,*lvgad,*gad,*button[2];
  105. struct NewGadget ng;
  106. struct Hook hook;
  107. struct TreeList tl;
  108. APTR   vi,pool;
  109. int    fontheight,itemheight;
  110. BOOL   ende = FALSE;
  111.  
  112.  
  113. /**************** Requester ****************/
  114.  
  115.  
  116. long DoRequestA(STRPTR t,STRPTR gads,APTR args)
  117. {
  118.   struct EasyStruct es = {sizeof(struct EasyStruct),0,"TreeView-Request",NULL,NULL};
  119.  
  120.   es.es_TextFormat = t;
  121.   es.es_GadgetFormat = gads;
  122.   return(EasyRequestArgs(scr->FirstWindow,&es,0,args));
  123. }
  124.  
  125.  
  126. void ErrorRequest(STRPTR t,...)
  127. {
  128.   DoRequestA(t,"Ok",&t+1);
  129. }
  130.  
  131.  
  132. /**************** String functions ****************/
  133.  
  134.  
  135. STRPTR AllocString(STRPTR t)  // these will be freed at the end of the programme
  136. {
  137.   STRPTR s;
  138.  
  139.   if (!t || !*t)
  140.     return(NULL);
  141.  
  142.   if (s = AllocPooled(pool,strlen(t)+1))
  143.     strcpy(s,t);
  144.   return(s);
  145. }
  146.  
  147.  
  148. /**************** list functions ****************/
  149.  
  150.  
  151. void CloseAllTrees(struct MinList *tree)
  152. {
  153.   struct TreeNode *tn;
  154.  
  155.   foreach(tree,tn)
  156.   {
  157.     if (tn->tn_Flags & TNF_CONTAINER)
  158.     {
  159.       CloseAllTrees(&tn->tn_Nodes);
  160.       tn->tn_Flags &= ~TNF_OPEN;
  161.     }
  162.   }
  163. }
  164.  
  165.  
  166. /**************** main programme ****************/
  167.  
  168.  
  169. void processMsg(void)
  170. {
  171.   struct IntuiMessage *msg;
  172.   struct DropMessage *dm;
  173.   int    source,target;
  174.   int    i;
  175.  
  176.   while(!ende)
  177.   {
  178.     WaitPort(win->UserPort);
  179.     while(msg = GTD_GetIMsg(win->UserPort))
  180.     {
  181.       imsg = *msg;
  182.  
  183.  
  184.       if (imsg.Class == IDCMP_OBJECTDROP)      /* handle the IDCMP_OBJECTDROP message */
  185.       {
  186.         if ((dm = imsg.IAddress) && !dm->dm_Object.od_Owner)
  187.         {
  188.           if (dm->dm_Target)
  189.           {
  190.             target = dm->dm_Target->GadgetID;
  191.             source = dm->dm_Gadget->GadgetID;
  192.  
  193.             if (target > 1 && source == 1)   // Show or execute
  194.             {
  195.               struct TreeNode *tn = TREENODE(dm->dm_Object.od_Object);
  196.               char t[256];
  197.  
  198.               if (target == 2)
  199.                 strcpy(t,MULTIVIEW " ");
  200.               else
  201.                 t[0] = 0;
  202.               strcat(t,"\"");
  203.               strcat(t,SEARCH_DIRECTORY);
  204.  
  205.               if (GetTreePath(tn,t+strlen(t),200))
  206.               {
  207.                 BPTR input;
  208.  
  209.                 strcat(t,tn->tn_Node.in_Name);
  210.                 strcat(t,"\"");
  211.                 if (input = Open(OUTPUT,MODE_OLDFILE))
  212.                 {
  213.                   if (SystemTags(t,SYS_Input,     input,
  214.                                    SYS_Output,    NULL,
  215.                                    SYS_Asynch,    TRUE,
  216.                                    SYS_UserShell, TRUE,
  217.                                    TAG_END) == -1)
  218.                   {
  219.                     Close(input);
  220.                     ErrorRequest("Execution failed:\n  %s",t);
  221.                   }
  222.                 }
  223.                 else
  224.                   ErrorRequest("Could not open output:\n",OUTPUT);
  225.               }
  226.             }
  227.             else if (target == source)     // only possible if target == 1
  228.               ErrorRequest("Sorry, but I can't move anything!");
  229.           }
  230.         }
  231.         else
  232.           DisplayBeep(NULL);
  233.       }
  234.       GTD_ReplyIMsg(msg);
  235.  
  236.       switch(imsg.Class)
  237.       {
  238.         case IDCMP_GADGETDOWN:
  239.           break;
  240.         case IDCMP_GADGETUP:
  241.           switch((gad = imsg.IAddress)->GadgetID)
  242.           {
  243.             case 1:
  244.             {
  245.               struct TreeNode *tn;
  246.               long   top;
  247.  
  248.               for(tn = (APTR)tl.tl_View.mlh_Head,i = 0;i < imsg.Code;tn = (APTR)tn->tn_Node.in_Succ,i++);
  249.               gad->UserData = tn;  tn = TREENODE(tn);
  250.  
  251.               //ToggleTree(gad,tn,&imsg);
  252.  
  253.               /** ToggleTree(gad,tn,&imsg) does something like this: **/
  254.  
  255.               GT_GetGadgetAttrs(gad,win,NULL,GTLV_Top,&top,TAG_END);
  256.  
  257.               if (MouseOverTreeKnob(tn,gad->TopEdge+2+(imsg.Code-top)*itemheight,&imsg))
  258.               {
  259.                 long in,height = (gad->Height-4)/itemheight;
  260.  
  261.                 GT_SetGadgetAttrs(gad,win,NULL,GTLV_Labels,~0L,TAG_END);
  262.  
  263.                 if ((in = ToggleTreeNode(&tl.tl_View,tn)) && imsg.Code+1+in > top+height)
  264.                   top += imsg.Code+in+1-top-height;
  265.  
  266.                 GT_SetGadgetAttrs(gad,win,NULL,GTLV_Labels,&tl.tl_View,GTLV_Top,top,TAG_END);
  267.               }
  268.               break;
  269.             }
  270.           }
  271.           break;
  272.         case IDCMP_MENUPICK:
  273.           i = 0;
  274.           switch ITEMNUM(imsg.Code)
  275.           {
  276.             case 1:
  277.               i = TNF_OPEN;
  278.             case 0:
  279.             {
  280.               struct TreeNode *ln,*tn;
  281.  
  282.               GT_SetGadgetAttrs(lvgad,win,NULL,GTLV_Labels,~0L,TAG_END);
  283.  
  284.               foreach(&tl,ln)
  285.               {
  286.                 tn = TREENODE(ln);
  287.  
  288.                 if ((tn->tn_Flags & TNF_OPEN) == i)
  289.                   ToggleTreeNode(&tl,tn);
  290.               }
  291.               if (ITEMNUM(imsg.Code) == 1)      // close all sub-directories, see above
  292.                 CloseAllTrees(&tl.tl_Tree);
  293.  
  294.               GT_SetGadgetAttrs(lvgad,win,NULL,GTLV_Labels,&tl.tl_View,GTLV_Top,0,TAG_END);
  295.               break;
  296.             }
  297.             case 3:
  298.               ErrorRequest("TreeView - a gtdrag example\n\n©1999 pinc Software.\nAll Rights Reserved.");
  299.               break;
  300.             case 4:
  301.               ende = TRUE;
  302.               break;
  303.           }
  304.           break;
  305.         case IDCMP_CLOSEWINDOW:
  306.           ende = TRUE;
  307.           break;
  308.       }
  309.     }
  310.   }
  311. }
  312.  
  313.  
  314. struct Window *initWindow(void)
  315. {
  316.   struct Window *win;
  317.  
  318.   gad = CreateContext(&glist);
  319.  
  320.   ng.ng_LeftEdge = 8;
  321.   ng.ng_TopEdge = fontheight+7;
  322.   ng.ng_Width = 184;
  323.   ng.ng_Height = 14*itemheight+4;
  324.   ng.ng_VisualInfo = vi;
  325.   ng.ng_TextAttr = scr->Font;
  326.   ng.ng_GadgetText = NULL;
  327.   ng.ng_UserData = NULL;
  328.   ng.ng_GadgetID = 1;
  329.   lvgad = CreateGadget(LISTVIEW_KIND,gad,&ng,GTLV_Labels,&tl,GTLV_CallBack,&hook,GTLV_ItemHeight,itemheight,TAG_END);
  330.  
  331.   ng.ng_TopEdge += ng.ng_Height;
  332.   ng.ng_LeftEdge = 8;
  333.   ng.ng_Height = fontheight+4;
  334.   ng.ng_Width >>= 1;
  335.   ng.ng_Flags = PLACETEXT_IN;
  336.   ng.ng_GadgetText = "Show";
  337.   ng.ng_GadgetID++;
  338.   button[0] = CreateGadget(BUTTON_KIND,lvgad,&ng,GA_Immediate,TRUE,TAG_END);
  339.  
  340.   ng.ng_LeftEdge += ng.ng_Width;
  341.   ng.ng_GadgetText = "Execute";
  342.   ng.ng_GadgetID++;
  343.   button[1] = CreateGadget(BUTTON_KIND,button[0],&ng,TAG_END);
  344.  
  345.   if (win = OpenWindowTags(NULL,WA_Title,   "gtdrag - TreeView",
  346.                                 WA_Flags,   WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE,
  347.                                 WA_IDCMP,   IDCMP_CLOSEWINDOW | DRAGIDCMP | IDCMP_MENUPICK,
  348.                                 WA_Width,   200,
  349.                                 WA_NewLookMenus,TRUE,
  350.                                 WA_Height,  itemheight*14+3*fontheight+10,
  351.                                 WA_Gadgets, glist,
  352.                                 TAG_END))
  353.   {
  354.     SetMenuStrip(win,menu);
  355.     GT_RefreshWindow(win,NULL);
  356.  
  357.     GTD_AddGadget(LISTVIEW_KIND,lvgad,win,GTDA_RenderHook,&hook,
  358.                                           GTDA_Type,      ODT_TREENODE,
  359.                                           GTDA_ItemHeight,itemheight,
  360.                                           GTDA_Same,      TRUE,
  361.                                           GTDA_TreeView,  TRUE,
  362.                                           TAG_END);
  363.     GTD_AddGadget(BUTTON_KIND,button[0],win,TAG_END);
  364.     GTD_AddGadget(BUTTON_KIND,button[1],win,TAG_END);
  365.  
  366.     return(win);
  367.   }
  368.   return(NULL);
  369. }
  370.  
  371.  
  372. void GetDirectoryTree(struct MinList *tree,STRPTR name,int depth)
  373. {
  374.   APTR edbuffer;
  375.   BPTR lock;
  376.  
  377.   if (!depth)
  378.     return;
  379.  
  380.   if (edbuffer = AllocPooled(pool,PUDDLESIZE))
  381.   {
  382.     if (lock = Lock(name,ACCESS_READ))
  383.     {
  384.       struct ExAllControl *eac;
  385.       struct ExAllData *ed;
  386.       long   more;
  387.  
  388.       if (eac = AllocDosObject(DOS_EXALLCONTROL,NULL))
  389.       {
  390.         struct TreeNode *tn;
  391.  
  392.         do
  393.         {
  394.           more =  ExAll(lock,edbuffer,PUDDLESIZE,ED_TYPE,eac);
  395.  
  396.           if (eac->eac_Entries == 0)
  397.             break;
  398.  
  399.           for(ed = edbuffer;ed;ed = ed->ed_Next)
  400.           {
  401.             if (!strcmp(ed->ed_Name+strlen(ed->ed_Name)-5,".info"))
  402.               continue;
  403.  
  404.             tn = AddTreeNode(pool,tree,AllocString(ed->ed_Name),NULL,(ed->ed_Type == ST_USERDIR ? TNF_CONTAINER | TNF_HIGHLIGHTED : TNF_NONE) | TNF_SORT);
  405.  
  406.             if (tn && ed->ed_Type == ST_USERDIR && depth > 1)
  407.             {
  408.               BPTR old;
  409.  
  410.               old = CurrentDir(lock);
  411.               GetDirectoryTree(&tn->tn_Nodes,ed->ed_Name,depth-1);
  412.               CurrentDir(old);
  413.             }
  414.           }
  415.         } while(more);
  416.  
  417.         FreeDosObject(DOS_EXALLCONTROL,eac);
  418.       }
  419.       UnLock(lock);
  420.     }
  421.     FreePooled(pool,edbuffer,PUDDLESIZE);
  422.   }
  423. }
  424.  
  425.  
  426. void init(void)
  427. {
  428.   CopyMem(GTD_GetHook(GTDH_TREE),&hook,sizeof(struct Hook));
  429.   hook.h_Data = (APTR)FindColor(scr->ViewPort.ColorMap,0x44444444,0x44444444,0x44444444,-1);
  430.  
  431.   NewList((struct List *)&tl.tl_Tree);
  432.   GetDirectoryTree(&tl.tl_Tree,SEARCH_DIRECTORY,SEARCH_DEPTH);
  433.  
  434.   InitTreeList(&tl);
  435. }
  436.  
  437.  
  438. void main(int argc, char **argv)
  439. {
  440.   if (GTDragBase = OpenLibrary("gtdrag.library",3))
  441.   {
  442.     if (GTD_AddApp("treetest",GTDA_NewStyle,TRUE,TAG_END))
  443.     {
  444.       if (pool = CreatePool(MEMF_PUBLIC | MEMF_CLEAR,PUDDLESIZE,PUDDLESIZE))
  445.       {
  446.         if (scr = LockPubScreen(NULL))
  447.         {
  448.           vi = GetVisualInfo(scr,TAG_END);
  449.           fontheight = scr->Font->ta_YSize;
  450.           itemheight = fontheight+2;
  451.           init();
  452.  
  453.           if (menu = CreateMenus(NMenu,TAG_END))
  454.           {
  455.             if (LayoutMenus(menu,vi,GTMN_NewLookMenus, TRUE,
  456.                                     TAG_END))
  457.             {
  458.               if (win = initWindow())
  459.               {
  460.                 processMsg();
  461.                 CloseWindow(win);
  462.               }
  463.               FreeGadgets(glist);
  464.               FreeMenus(menu);
  465.             }
  466.           }
  467.           FreeVisualInfo(vi);
  468.           UnlockPubScreen(NULL,scr);
  469.         }
  470.         DeletePool(pool);
  471.       }
  472.       GTD_RemoveApp();
  473.     }
  474.     CloseLibrary(GTDragBase);
  475.   }
  476.   else
  477.     ErrorRequest("Could not open the gtdrag.library v3 or higher.");
  478. }
  479.